#include <iostream>

using namespace  std;
typedef struct BinarySearchTree
{
     int data;
     int count;
     struct BinarySearchTree* left;
     struct BinarySearchTree* right;
     BinarySearchTree()
     {

     }
     BinarySearchTree(int x)
     {
         this->data=x;
         this->count=1;
         this->left=NULL;
         this->right=NULL;
     }
}BinarySearchTree;
//二叉搜索树的增删查

//查
//1.递归版
BinarySearchTree* findX(BinarySearchTree* root,int x)
{
    if(root->data==x)
        return root;
    else if(root->data<x)
    {
      return findX(root->right,x);
    } else
    {
        return findX(root->left,x);
    }
}
//2.非递归版
BinarySearchTree* find_X(BinarySearchTree* root,int x)
{

     while(root)
     {
         if(root->data==x)
         {
             return root;
         } else if(root->data>x)
         {
             root=root->left;
         } else
         {
             root=root->right;
         }
     }
     return NULL;

}

//借助引用事半功倍 插入
void  insertX(BinarySearchTree* &root,int x)
{
    //沿着某条路径找只要为空就插入进去
   if(!root)
   {
       root=new BinarySearchTree(x);
   } else
   {
       if(root->data>x)
       {
           insertX(root->left,x);
       } else
       {
           insertX(root->right,x);
       }
   }
}

//删除某个结点
//借助引用事半功倍 插入
void  deleteX(BinarySearchTree* &root,int x)
{
    //不存在该结点
     if(root==NULL){
         return ;
     } else
     {
         if(root->data==x)
         {
            //如果当前结点是要删除的结点
            //如果当前结点是叶子结点直接删除
            if(!root->left&&!root->right)
            {
                root=NULL;
            }
            //如果有左孩子 用左子树最大的结点替代
            else if(root->left)
            {
                BinarySearchTree* p=root->left;
                while(p->right)
                {
                    p=p->right;
                }
                //将p赋值给root的left 然后将p赋空

                //用p的信息覆盖root的信息
                p->right=root->right;//把左右孩子接上
                p->left=root->left;
                root=p;
                p=NULL;
            }
            //如果没有左孩子 有右孩子 用右子树最小的结点替代
            else
            {
               BinarySearchTree* p=root->right;
               while(p->right)
               {
                   p=p->right;
               }
                p->right=root->right;//把左右孩子接上
                root=p;
                p=NULL;

            }
         } else if(root->data>x)
         {
             deleteX(root->left,x);
         } else
         {
             deleteX(root->right,x);
         }
     }
}


//初始化二叉排序树
void init(BinarySearchTree* &root)
{
   int n;
   cin>>n;
    for (int i = 0; i < n; ++i) {
        int x;
        cin>>x;
        insertX(root,x);
    }
}

//前序遍历BST
void preorder(BinarySearchTree* root)
{
    if(root)
    {
        preorder(root->left);
        cout<<root->data<<" "<<root->count<<endl;
        preorder(root->right);
    }
}
int main() {
    BinarySearchTree* root=NULL;
    init(root);
    preorder(root);
    int x;
    cin>>x;
    BinarySearchTree* res=findX(root,x);
    if(res) //找到了
    {
        //count++
        res->count+=1;
    } else
    {
         //插入其中
         insertX(root,x);
    }

    cout<<"操作之后----------"<<endl;
    preorder(root);


    cout<<"删除之后----------"<<endl;
    cin>>x;
    deleteX(root,x);
    preorder(root);
    return 0;
}
